<?php
/*
 *
TODO grid edit img
var input = $('.EditTable input[id=link]')
var image = input.val()
var container = input.parent()
container.find( 'input' ).remove();
container.html(image)

TODO разобраться с модульными js-никами и файлами стилей. От них стоит отказаться

TODO Проверять ЗДЕСЬ - если не админ, перекидывать на модуль login
if(!User::isAdmin()) return null;

TODO исправить редирект на страницу 404

TODO Сделать ловушку исключений и писать их в лог

TODO выбрать метод передачи урл-параметров: как в Зенде или как в Веб-билдере

TODO надо ли редиректить на /404 - отдельный урл, - если ресурс не найден
Сбойный урл остается висеть, загловок 404, страница - специальная заглушка

TODO стандартное имя точки входа секции виртуального модуля

TODO сделать пути к картинкам в css "....../Image/file.png"


TODO кэш скриптов и стилей; вывод public_path в самом начале

TODO Сейчас 404 реагирует только на http://remontik.kh.ua/about/неправильный_экшен.

TODO стили и скрипты модуля читать из файла и тулить в <head> сайта

Сделать то же самое для виртуальных модулей

***************** Секции и фотографии **************
виртуальный модуль может иметь секции.

Фото может быть привязано:
  - к модулю
  - к секции модуля
  - к виртуальному модулю
  - к секции виртуального модуля

Эта связь реализуется в т. photo через одно из трех полей:
    modul_id
    vmodul_id
    section_id
Иначе, они равны NULL.

В модуле грузим контент.
  а) Мы в точке входа секции, тогда
    - если секции есть, загружаем фото для секции
  б) Мы в точке входа модуля
    - ищем фото для модуля

[!] Секция - это просто еще одна точка входа.

Файл фото лежит в ..../Image/<имя модуля/виртуального модуля>/[sm_][section_id]<буквы-цифры>.jpg
*/

class Controller extends controllerInterface{
// Класс Фронт-контроллера
    protected $view;
    protected $model;
    protected $BD = null;
    protected $registry;

    static public $instance; // instance of modul controller

    public $modul_index = ''; // face
    public $virtual_modul_index = '';
    public $modul_name = ''; // Face
    public $virtual_modul_name = '';
    public $virtual_modul_id = null;
    public $modul_controller;
    public $modul_html;
    public $modul_info ;
    public $modul_class_name = ''; // FaceModul
    public $method;
    public $ArgMod;
    public $html = '';
    public $css_arr = array();
    public $js_arr = array();

    static public $front_controller_instance;

    protected $output; // html, сгенерированный конкретным модулем 
    protected $widget_enter_data;  // входные данные для виджетов

    private $modul  = false; // контроллер конкретнрого модуля
    private $is_virtual_modul  = false; // модуль реальный
    private $no_render  = false;



    function __construct($registry = null){

        if($registry !== null ){
            $this->registry = $registry;
            $this->BD = $this->registry->get('db');
        } else {
            $this->registry = Registry::getInstance();
        }

        //
        $this->loadStartJS();
        // FirePHP
        //$firephp = FirePHP::getInstance(true);
        //$this->registry->set('firephp', $firephp);

        // модель
        //$this->model = new Model($registry);
        //$registry->set('Model', $this->model);

        $this->model = $registry->get('Model');

        // представление    
        //$View = new View($registry);
        $this->view = View::getInstance();
        $registry->set('View', $this->view);

        // Берем 1 аргумент URI
        $this->modul_index = $this->registry->request->get(1);



        // Проверка авторизации
        if($registry->has('zone') ){
            if($registry->zone == 'backend' AND $this->modul_index != 'login'){
                $request_uri = $_SERVER['REQUEST_URI'];
                if(!User::isAdmin()){

                    $script_name = rtrim(dirname($_SERVER['SCRIPT_NAME'])); // /admin_remontik

                    $request_uri = str_replace($script_name,"",$request_uri);
                    $request_uri = str_replace("/","",$request_uri);

                    Registry::getInstance()->session->request_uri = $request_uri;

                    header("Location:" . PUBLIC_URL . "/login");

                    return null;
                } else {
                    // Если пользователь - админ, ничего не делаем
                }
            }
        }

        /// fb(Registry::getInstance()->session);

        // Модуль по умолчанию
        if( $this->modul_index == '' )   $this->modul_index = "face";
        // Переброс на альтернативный контроллер
        if( $this->modul_index == 'core' ) return $this->loadCoreController();

        // [!]
        // Передать управление контроллеру модуля
        // Контроллер модуля вернет html и, возможно, массив входных данных для установленных виджетов
        // вызвать требуемые виджеты, получить от них html
        // Передать html модуля и html виджетов во View
        // Получепнный отклик вернуть Контроллеру, который инициирует вывод
        //
        // Контроллер модуля создает объекты: new Modul.Model, new Modul.View и возвращает html-код модуля + данные на вход нужных виджетов
        // Фронт-контроллер проверяет массив на предмет данных для виджетов, если надо, опрашивает эти виджеты и берет их ответы, 
        // после чего отдает кол модуля и html-код виджетов Представлению
        //
        // [?] Представление выводит код самостоятельно или вывод инициирует Фронт-контроллер?  
        // --------------------------------------------
        // [!]
        // Работа Фронт КОнтроллера.
        // Разобрать URL
        // Создать объект ModulController (Отработать шаблон Factory)
        // В случае неуспеха выдать ошибку, в случае успеха - получить $modul_html и $widget_inputdata_arr
        // срендерить html виджетов
        // Создать объект Model
        // (!) здесь возможен вызов дополнительной логики из Модели движка. 
        // срендерить шаблон (main.tpl + $modul_html + widget html)
        // Создать обхект View
        // echo $html




        //  Выдать модуль        
        if($this->modulExists() === true){
            //TODO if запрос из ajax

            //TODO if передано число


            // Название виртуального модуля
            $this->virtual_modul_index = mb_convert_case( $this->model->translitBackToCyr($this->modul_index),MB_CASE_TITLE, "UTF-8" );
            $this->registry->set('virtual_modul_index',$this->virtual_modul_index); // Контакты

            // Название реального модуля и класса ([!] $this->modul_index перетирается)
            $this->registry->set('modul_class_name',$this->modul_class_name); // FaceModul
            $this->modul_index = substr($this->modul_class_name, 0, -5);

            $this->registry->set('modul_index',$this->modul_index); // Face

            // Взять базовый шаблон (перенесено сюда с конца конструктора)
            // [!] Вызывается после установки в $this->modul_index индекса реального модуля
            // [!] Если $this->modul_index содержит виртуальный индекс, будет загружен index.tpl
            $this->view->tpl = $this->getBasicModulTpl();  // _main.tpl, например
            Registry::getInstance()->set('basic_modul_tpl', $this->view->tpl);

            // Виртуальный или реальный модуль
            if( $this->modul_index != $this->virtual_modul_index ){
                $this->is_virtual_modul = true;
            }

            // создаем контроллер модуля
            try {
                $name = $this->modul_class_name;

                $obj = new $name($this->registry);

                if(is_object($obj)){
                    $this->modul_controller = $obj;
                } else
                    $this->modul_controller = new $this->modul_class_name($this->registry);

            } catch (Exception  $e) {
                echo 'Caught exception: ',  $e->getMessage(), "\n";
            }


            $err_404 = false;


            // ---------------------------
            // Объект Model
            //$this->model = new Model(); 
            //$this->smarty = $this->model->getParam('smarty');


            if($second_url_arg =  $this->registry->request->get(2) /*AND ($this->is_virtual_modul === false)*/ ){
                ////  AND ($this->registry->get('virtual_modul_index').'') == '' ) {
                // Если есть второй параметра урла и мы работаем с реальным модулем

                // [!] Здесь можно вставить парсинг урл для отлавливания особых адресов, напр, админских


                if($second_url_arg == 'param'){
                    // [!] DERPECATED
                    // 'param' означает, что за ним идут параметры для основного экшена модуля Face::actionFaceBasic()
                    // TODO проверить, нужна ли данная секция
                    $this->modul_controller->action = 'action' . $this->modul_name . 'Basic' ;
                    if( ($this->registry->get('virtual_modul_index')) != '')
                        $this->modul_controller->action = 'action' . $this->registry->get('virtual_modul_index') . 'Basic';

                    // [!] получить массив параметров и передать их модулю
                    $basic_act_param = array('1'=>1);
                    $this->modul_controller->basic_act_param = $basic_act_param;

                } else {
                    // рассматриваем второй параметр как имя экшена или точки входа, или как название раздела

                    // пытаемся взять section_id
                    $s_id_1 = (int)$this->model->getSectionIdByName( $second_url_arg );
                    $s_id_2 = (int)$this->model->getSectionIdByName($this->model->translitBackToCyr($second_url_arg));

                    if( ($section_id = $this->model->getSectionIdByName($this->model->translitBackToCyr($second_url_arg)) ) !== false)
                        $registry->set('section_id', $section_id);

                    $second_url_arg = $this->model->translitEncodedURL($second_url_arg);
                    $second_url_arg = preg_replace('/_/i','',$second_url_arg);




                    $this->method = $second_url_arg; // $this->registry->request->get(2)

                    if($this->methodExists()){
                        // если есть точка входа, передаем управление ей

                        $this->modul_controller->action = $this->method; // здесь уже готовый метод типа actionFaceAsd

                    } else {
                        // иначе, пробуем загрузить раздел через роутер

                        // if( $use_router )

                        // [?] для роутера нужны записи в базе
                        if((int)$s_id_1 > 0 OR (int)$s_id_2 > 0){
                            $this->modul_controller->action = 'sectionLoader';

                            if($s_id_1 > 0) $registry->set('section_id', (int)$s_id_1);
                            if($s_id_2 > 0) $registry->set('section_id', (int)$s_id_2);

                        } else {
                            // раздел не существует

                            if( (bool)$this->registry->request->get(3) === false ){
                                // если третьего параметра нет, выдать ошибку
                                $err_404 = true;
                                $this->view->Set('mess','');
                                $this->view->narrow_design = 1;
                                $modul_html =  $this->view->fetch('404.tpl');

                            } else {
                                // если третий параметр есть, считаем, что урл содержит переменную и значение.
                                // Передаем управленеи основной точке входа реального модуля
                                $this->modul_controller->action = 'action' . $this->modul_name . 'Basic' ;
                            }

                        }
                        // else

                    }
                }
                // } elseif($second_url_arg = $this->getURIarg(1)
                //    AND ($this->registry->get('virtual_modul_index').'') != '' ){
                // если есть второй параметр урла и модуль виртуальный

            } else {
                // если нет второго аргумента в урле

                // $this->capitalizeFirst($this->modul_index)

                //  базовый экшн реального модуля
                $this->modul_controller->action = 'action' . $this->modul_name . 'Basic' ;

                ////if( ($this->registry->get('virtual_modul_index')) != ''){
                if( $this->is_virtual_modul ){
                    // [!] Прямой псевдоним - альтернативное имя реального модуля.
                    // Виртуальное имя, не являющееся прямым псевдонимом, ссылается на самостоятельный action.

                    if( (string)$this->registry->request->get(2) == '' ){
                        if( $this->registry->get('is_direct_alias') ){
                            // Если это прямой псевдоним, загрузить action настоящего модуля,
                            $this->modul_controller->action = 'action' . $this->registry->get('modul_index') . 'Basic'; // либо виртуального
                        } else {
                            // иначе - action виртуального модуля.

                            $action_virtual = "actionVirtual" . ucfirst( preg_replace('/[^a-z]/i', '', $this->model->translit($this->registry->get('virtual_modul_index'))) );
                            ///fb($action_virtual); // [!] TEST action name

                            if( $this->methodExists($action_virtual) )
                                // Грузим actionVirtualKontakty()
                                $this->modul_controller->action = $action_virtual;
                            else
                                // Грузим actionКонтактыBasic()
                                $this->modul_controller->action = 'action' . $this->registry->get('virtual_modul_index') . 'Basic'; // либо виртуального
                        }
                    } else {
                        // Есть второй аргумент


                        $action = 'action' .
                            $this->model->translitBackToCyr( $this->registry->request->get(1) ) .
                            $this->model->translitBackToCyr( $this->registry->request->get(2) ) ;
                        ///fb($action);
                        if($this->methodExists($action)){
                            $this->modul_controller->action = $action; // actionPlitkaStorePhoto
                        } else {
                            $action = 'action' .
                                ucfirst ( $this->model->translitBackToCyr( $this->registry->request->get(1) ) ) .
                                'Basic'  ;
                            $this->modul_controller->action = $action; // actionPlitkaBasic
                        }
                    }

                }
                /* else  {
                    //  базовый экшн реального модуля
                    // $this->modul_controller->action = 'action' . $this->modul_name . 'Basic' ;
                } */

            }
            // входные данные для виджетов
            // [!] передать этот массив в обработку объекту widget
            // [!] вместо этого - класть этот массив в соответсвующую ячейку registry->widgets_arr
            // предполагается, что модуль уже положил инпут_дату в реестр, откуда ее вытащит Widget
            // $this->registry->widget_inputdata_arr = $this->modul_controller->widget_inputdata_arr;

            //
            $this->addModulCss($this->modul_name);

            // загрузить /Modul/scripts.js
            $this->addModulJs($this->modul_name);

            //$this->addJs('jquery.blockUI.js', $get_script_from_standard_dir = true); 
            //$this->addJs('jquery.form.js', $get_script_from_standard_dir = true);

            // [!] Если базовые js-ки добавляются здесь, это, по идее, медленее и
            // возможно, что сам jquery загрузится позже библиотек
            // $this->addJs('jquery.js',true );



        } else {
            // модуль не существует
            // [!]   передать управление View, чтобы он вывел шаблон 404.tpl 
            // $this->view->get404() 
            $err_404 = true; // TODO Registry::getInstance() -> get('error404')
            $this->view->Set('mess','');
            $modul_html =
                $this->view->fetch('404.tpl');
        }


        // передать управленеи модулю
        if($err_404 !== true AND is_object($this->modul_controller)){
            // [!] раскоментить
            //$this->modul_controller->action = 'dsc';

            $this->modul_controller->load();

            if( Registry::getInstance() -> get('error404') === true ){

                $this->view->Set('mess','');
                $modul_html = $this->view->fetch('404.tpl');
            } else {
                // берем html-код, сгенерированный модулем
                $modul_html = $this->modul_controller->getHtml();
            }

        } else {
            //TODO
            // ошибка 404
        }

        // опрос виджетов на предмет html-кода       
        $this->setWidgetsHtml();






        // [!] Здесь можно установить переменные
        // эта 'asd' затрет asd, инициализированную в модуле
        // $this->view->Set('asd',$modul_html);
        // Здесь выставлять html, сгенеренный виджетами?

        $reg = Registry::getInstance();
        if( $reg->has('js') ) $js = $reg->get('js');

        if(isset($js)) if( is_array($js) )
            if(isset($this->js_arr)) if( is_array($this->js_arr) ) $this->js_arr = array_merge($this->js_arr, $js);

        // Вывод
        $js_to_laod =  Registry::getInstance() -> get("js");

        // TODO сделать сборку массива css_arr
        $this->view->Set('css', $this->css_arr);
        $this->view->Set('js', /*$this->js_arr*/ $js_to_laod );

        $this->view->Set('modul_html',$modul_html);     //session_destroy(); $reg->set('session',null);  // [!] test



        $this->no_render = $this->registry->no_render ;

        // пытаемся рендерить окончательную страницу
        //TODO если no-render, то view вообще не нужно! А также, подключение стилей и скриптов
        if($this->no_render){
            $this->html = null;

        } else {

            try {
                $this->view->jquery = $this->jquery();

                if($this->registry->has('head_code'))
                    $this->view->headCode = "<script type=\"text/javascript\">" . $this->registry->head_code . "</script>";

                if($this->registry->has('head_code_dynamic'))
                    $this->view->headCodeDynamic = "<script type=\"text/javascript\">
                    $(function() {
                    " . $this->registry->head_code_dynamic . "
                    });
                    </script>";

                $this->view->headScript = $this->parseHeadScriptArr();

                $this->initialStyleSheets();
                $this->view->headLink = $this->parseHeadLinkArr();

                $this->view->render();

            } catch (Exception $e) {
                // View error
                fb($e->getMessage());
                //fb ( $e->getFile() );
                //asd( $e->getTrace() );
                //fb("Code: ".$e->getCode());
                //fb("Line: ".$e->getLine());
                //FIXME раскоментить на живом сайте
                //header("/");
            }


            $this->html = $this->view->output();
        }




        #
        self::$front_controller_instance = $this;

    } // -- __construct()

    function setWidgetsHtml(){
        //TODO нужен ли этот метод

        $Widget = $this->registry  -> get('Widget');

        // Можно процессить все виджеты, а можно только глобальные
        // Любой виджет можно срендерить и вывести из модуля (т.к. по логике, модуль - это единица завершенного вида)
        $Widget->constructWidgetsArr($this->getBasicModulTpl(), $process_globals_only = true);

        $widgets_arr = $this->registry->get('widgets_arr');

        if(is_null($widgets_arr) OR $widgets_arr === false) return null;

        // TODO
        // [!] сконструировать массив виджетов, привязанных к шаблону и вытянуть код именно их

        foreach($widgets_arr as $widget){
            $name = $widget['widget']['widgets_name'];
            $html = $widget['output_html'];
            $this->view->Set($name.'_widget',$html);  // {$Login_widget}
        }

    } // --

    function loadStartJS(){

        $simple_js = array();

        #
        //$host = 'http://' . $_SERVER['HTTP_HOST'] . '/'; //remontik.kh.ua/';";
        //$host = PUBLIC_URL . '/';
        //$js = "var basic_path = '$host';";
        //$js = "<script  type='text/javascript'>  $js  </script>";
        $js = '';




        // $simple_js[] = 'jquery-1.9.1.js';
        //$simple_js[] = 'jquery.js';
        //$simple_js[] = 'grid.locale-ru.js';
        //$simple_js[] = 'jquery.jqGrid.min.js';
        $simple_js[] = 'jquery.cycle.js';
        // $simple_js[] = 'jquery-ui-1.10.3.custom.min.js';
        $simple_js[] = 'scripts.js';
        $simple_js[] = 'scripts2.js';

        #
        foreach($simple_js as $k => $script){
            $this->addJs($script,true );
        }



        #
        $js_to_load =  Registry::getInstance() -> get("js");

        if(isset($js_to_load)){
            if(is_array($js_to_load)){
                if(($res = array_search($js, $js_to_load)) === false){
                    // Массив есть, но в нем нет данной строчки
                    $js_to_load[] = $js;
                    Registry::getInstance() -> set("js", $js_to_load);
                }
            } else {
                $arr[] = $js;
                Registry::getInstance() -> set("js", $arr);
            }
        } else {
            // Если массива еще не было
            $arr[] = $js;
            Registry::getInstance() -> set("js", $arr);
        }


    }

    function loadCoreController(){
        // [URL] /core/controllername/actionname

        $core_controller_name = $this->registry->request->get(2);

        if($core_controller_name === false) die('Bad controller name'); //header("Location:/badurl/"); // редирект на заведомо отсутсвующий УРЛ

        try {
            //$core_controller_name = ucfirst($core_controller_name) . 'Controller';
            $core_controller_name = $core_controller_name . 'Controller';
            $Controller = new $core_controller_name ();
        } catch (Exception  $e) {
            // TODO записывать исключение в лог
            // fb($e->getMessage());
        }

        if(($action_name = $this->registry->request->get(3)) === false)  $Controller->action = 'basic';
        else $Controller->action = $action_name;

        $method_name = $action_name . "Action";
        ///fb($action_name); // TEST
        ///fb($method_name);
        if(method_exists ( $Controller, $method_name )) $Controller->$method_name();
        else die('Bad method name'); // можно вместо этого писать в логи и редиректить куда-либо



        exit;
    }

    /*
    public static function action(){
        //die(var_dump(__CLASS__));
        $obj = static::getInstance();
         
        //$method = $obj->action;
        //$obj->$method();  
        
        //die(var_dump($obj->action));
    } // --
    */

    function addModulCss($modul){
        //TODO брать файл и валить его в кэш, чтобы скрыть путь к файлу
        $filename = 'style.css';
        $css = PUBLIC_URL . "/Moduls/$modul/$filename";
        if(is_file($css)){
            $css_str = "<link media=\"screen\" href=\"/Moduls/$modul/$filename\" type=\"text/css\" rel=\"stylesheet\">";
            $this->css_arr[] = $css_str;
        }
    } // -- addModulCss

    function addModulJs($modul){
        //TODO брать файл и валить его в кэш, чтобы скрыть путь к файлу
        $js_to_laod =  Registry::getInstance() -> get("js");

        $filename = 'script.js';
        $js = PUBLIC_PATH . "/Moduls/$modul/$filename";

        if(is_file($js)){
            $js_str = "<script src='". PUBLIC_URL . "/Moduls/$modul/$filename' type='text/javascript'></script>";

            if(isset($js_to_laod)){
                if(is_array($js_to_laod)){
                    if(($res = array_search($js_str, $js_to_laod)) === false){
                        // Массив есть, но в нем нет данной строчки
                        $js_to_laod[] = $js_str;
                        Registry::getInstance() -> set("js", $js_to_laod);
                    }
                } else {
                    $arr[] = $js_str;
                    Registry::getInstance() -> set("js", $arr);
                }
            } else {
                // Если массива еще не было
                $arr[] = $js_str;
                Registry::getInstance() -> set("js", $arr);
            }
        }

    } // -- addModulJs

    function addJs($js, $basic_dir = true, $enc = ''){

        $js_to_laod =  Registry::getInstance() -> get("js");

        $modul = $this->registry->get('modul_index');

        if($basic_dir) $prefix = "/js/";
        else $prefix = "/Moduls/$modul/";

        if($enc != '') $encoding = "charset='$enc'"; else  $encoding = '';

        $file = PUBLIC_PATH . $prefix . $js;


        if(is_file($file)){
            $js = "<script src='".PUBLIC_URL. "$prefix$js' type='text/javascript' $encoding></script>";

            if(isset($js_to_laod)){
                if(is_array($js_to_laod)){
                    if(($res = array_search($js, $js_to_laod)) === false){
                        // Массив есть, но в нем нет данной строчки
                        $js_to_laod[] = $js;
                        Registry::getInstance() -> set("js", $js_to_laod);
                    }
                } else {
                    $arr[] = $js;
                    Registry::getInstance() -> set("js", $arr);
                }
            } else {
                // Если массива еще не было
                $arr[] = $js;
                Registry::getInstance() -> set("js", $arr);
            }

        }

    }

    function addOuterJs($js){

        fb("[!] addOuterJs is Deprecated");

        $js_str = "<script src=".PUBLIC_URL."/'$js' type='text/javascript'></script>";
        $this->js_arr[] = $js_str;
        $r = Registry::getInstance();


    } // --

    /*
    function jsToRegistry(){
         $r = Registry::getInstance(); 
            if( $r->has('js') ){ 
              $reg_js = $r->get('js');var_dump($this->js_arr); 
              if(is_array($reg_js)){  
                foreach($reg_js as $k => $v){  
                  foreach($this->js_arr as $key => $val){
                    //if( strpos($v, $js) ) echo '+';
                    
                  }  
                }
              
                //$this->js_arr = array_merge( $this->js_arr, $reg_js);  
              }  
            } 
    }*/

    function output(){

        return $this->html;

    } // -- output

    function getBasicModulTpl(){
        //
        $tpl = 'index.tpl';

        $q = "SELECT * FROM moduls WHERE modul_index = '{$this->modul_index}' ";
        $r = mysql_query($q);
        if(!$r){

            $this->view->Set('mess','db connection was dropped due to getting basic tpl name in Controller::getBasicModulTpl(). Maybie U need to create database first');
            return '404.tpl';
        }
        if( mysql_num_rows($r) > 0){

            $this->modul_info = mysql_fetch_assoc($r);

            if(trim($this->modul_info['basic_tpl']) != '')
                $tpl = $this->modul_info['basic_tpl'];
        }



        return $tpl;
    } // --


    function modulExists($modul = false){
        //  true, если модуль с таким именем существует (настоящий или мнимый)


        if($modul === false) $modul = $this->modul_index;
        if($modul == false OR $modul == '') return false;

        if( $this->virtualModulExists($modul) ){

            // Этот ключ дублирует modul_alias
            Registry::getInstance() -> set('virtual_modul_index', $modul);

            $modul = Registry::getInstance() -> get('modul_index');
        }

        //TODO sql через вызов модели
        $q = "SELECT * FROM moduls WHERE modul_index = '$modul' ";
        $r = mysql_query($q); //fb($q); //SELECT * FROM moduls WHERE modul_index = 'face'
        if(!$r) return -1;
        if( mysql_num_rows($r) > 0){

            $this->modul_info = mysql_fetch_assoc($r);    //fb($this->modul_info);

            if( isset($this->modul_info['display'])  ){
                if( (int)$this->modul_info['display'] == 0 ){
                    fb("Modul is disabled");
                    return false;
                }
            }

            $modul = strtolower($modul);
            $first = substr($modul,0,1);
            $tail = substr($modul,1);
            $this->modul_name = strtoupper($first) . $tail; //var_dump($this->modul_name); // Face
            if(is_dir(SITE . "/Moduls/$this->modul_name")){

                if(is_file(SITE . "/Moduls/$this->modul_name/modul.$this->modul_name.php")){ //echo SITE . "/Moduls/$this->modul_name/modul.$this->modul_name.php";
                    require SITE . "/Moduls/$this->modul_name/modul.$this->modul_name.php";

                    if(class_exists($this->modul_class_name = $this->modul_name."Modul")){ // FaceModul

                        $this->registry->set('modul_info', $this->modul_info);
                        $this->registry->set('modul_id', $this->modul_info['id_modul']);

                        return true;
                    }  else {
                        fb('Modul class is not found');
                        return false;
                    }
                } else {
                    fb("File is not exists: ". SITE . "/Moduls/$this->modul_name/modul.$this->modul_name.php");
                }
            }  else {
                fb("Modul dir isnot exists");
            }
        }

        return false;
    } // --

    function virtualModulExists($modul){


        $q = "SELECT a.*, m.* FROM modul_alias a LEFT JOIN moduls m ON a.modul_id = m.id_modul  WHERE alias = '".$this->model->translitBackToCyr($modul)."' ";
        $r = mysql_query($q);
        if(!$r) return false;
        if( mysql_num_rows($r) > 0){

            /*
             * // другой вариант
              $alias = new ModulAliasModel('alias',$modul);
              $modul_alias = $alias->getData();
              if(isset($modul_alias[0])){
                  if( isset($modul_alias[0]['modul_id']) ){
                      //fb($modul_alias[0]['modul_id']);
                      //$this->modul_index = 'life';
                      //$this->modul_name = 'Life';
                      //$this->modul_class_name = 'LifeModul';
                      //return true;
    
    
                  }
              }
            */



            $modul_info = mysql_fetch_assoc($r);

            if($modul_info['is_direct_alias'] == 1) $is_direct_alias = true;
            else $is_direct_alias = false;

            $this->registry         -> is_direct_alias  = $is_direct_alias;
            $this->registry         -> modul_alias      = $this->model->translitBackToCyr($modul);
            $this->registry         -> modul_index      = $modul_info['modul_index']; // Real_modul text name
            $this->registry         -> virtual_modul_id = $modul_info['vmodul_id'];

            $this->virtual_modul_id = $modul_info['vmodul_id'];

            //fb($modul_info);

            return true;
        }

        return false;
    } // -- virtualModulExists


    function capitalizeFirst($str){
        $first = mb_substr($str,0,1, 'UTF-8');//первая буква
        $last = mb_substr($str,1);//все кроме первой буквы
        $first = mb_strtoupper($first, 'UTF-8');
        $last = mb_strtolower($last, 'UTF-8');
        return $first.$last;
    } // --

    /*
     *  Ищет метод в контроллере модуля
     */
    function methodExists($method = null){
        // ищем метод $this->modul_class_name::actionFaceAsd()
        // В случае неудачи - $this->modul_class_name::asd()

        if( !is_null($method) ){

            if(in_array($method,get_class_methods($this->modul_controller))) return true;

            return false;

        } else {
            // проверяем стандартный метод

            $method = "action" . $this->capitalizeFirst($this->modul_index) . $this->capitalizeFirst($this->method);
            // $this->modul_index; // face
            // $this->registry->get('modul_index'); // Face

            // ищем стандартную точку входа actionAboutMethod()
            if( method_exists($this->modul_class_name,$method) ){ $this->method = $method; return true; }

            // ищем прямой метод method()
            if( method_exists($this->modul_class_name,$this->method) )  return true;

            // ищем точку входа в субсекцию subactionMethod()
            $action_of_section = "subaction" . ucfirst( preg_replace('/[^a-z]/i', '', $this->model->translitEncodedURL($this->method)) );
            //fb($action_of_section); // [!] TEST action name

            if( $this->methodExists($action_of_section) ){
                //$this->modul_controller->action = $action_of_section;
                $this->method = $action_of_section;
                return true;
            }

            // ищем базовую точку входа в виртуальный модуль actionVirtualMethod()
            $action_virtual = "action" . $this->capitalizeFirst($this->virtual_modul_index)
                . $this->capitalizeFirst($this->method);
            // fb(preg_replace('/[-_]/i','',$action_virtual)); // TEST action name
            if( $this->methodExists( preg_replace('/[-_]/i','',$action_virtual) ) ){
                $this->method = $action_virtual;
                return true;
            }

            //TODO дополнить логику поиска метода, чтобы можно было попасть в actionPlitkaBasic()

        }

        return false;

    } // --   

    function getParam($param){
        // TODO
        // Можно юзать Registry::getInstance() -> get('request');

        $value = null;

        $request_uri = $_SERVER['REQUEST_URI'];
        $request_uri_arr = explode("/", $request_uri);

        # Get value from URL
        if(is_array($request_uri_arr)){
            if(($res = array_search($param, $request_uri_arr)) === false){
            } else {
                if(is_int($res))
                    if(isset($request_uri_arr[$res + 1]))
                        $value = $request_uri_arr[$res + 1];
            }
        }

        # Get value from GET
        # Get value from POST
        # Get value from Session
        # Get value from Cookie


        return $value;

    }

    static function getUriArgument( $index = null){
        // аналог getURIarg()
        // Нумерация аргументов начинается с 1

        fb("getUriArgument is deprecated");

        $arr_is_empty = true;

        $arg_mod  = false;

        if(!is_null($index)){
            $index--;

            $request_uri_arr = explode("/", $_SERVER['REQUEST_URI']);

            for($i=0; $i<count($request_uri_arr); $i++){
                if($request_uri_arr[$i] != '') $arr_is_empty = false;
                else $request_uri_arr[$i] = false;
            }

            if($arr_is_empty) return false;

            for($i=0; $i<count($request_uri_arr); $i++){
                if($request_uri_arr[$i] !== false) $arg_mod[] = $request_uri_arr[$i];
            }

            if(isset($arg_mod[$index])){
                preg_match("/\?/",$arg_mod[$index],$matches);

                if(isset($matches)){
                    if(isset($matches[0])){
                        return $matches[0];
                    }
                    else
                        return $arg_mod[$index];
                } else
                    return $arg_mod[$index];
            }
        }



        return false;
    }

    function getURIarg( $index = null ){


        return $this->registry->request->get(++$index);


        //$modul_index = 'main';
        $arr_is_empty = true;

        //if (isset($index)) $index--;
        // создаем массив URI-аргументов
        //if(isset($arg_arr)) unset($arg_arr);
        $request_uri = $_SERVER['REQUEST_URI'];
        $request_uri_arr = explode("/", $request_uri);

        for($i=0; $i<count($request_uri_arr); $i++){
            if($request_uri_arr[$i] != '') $arr_is_empty = false;
            else $request_uri_arr[$i] = false;
        }

        if($arr_is_empty) return false;

        for($i=0; $i<count($request_uri_arr); $i++){
            if($request_uri_arr[$i] !== false) $arg_mod[] = $request_uri_arr[$i];
        }// var_dump($arg_mod);


        if(isset($arg_mod)){
            if(isset($index)){
                if(isset($arg_mod[$index])){
                    preg_match("/\?/",$arg_mod[$index],$matches);

                    if(isset($matches)){
                        if(isset($matches[0])){
                        } // return false;
                        else
                            return $arg_mod[$index];
                    } else
                        return $arg_mod[$index];
                }
            } else {
                return $arg_mod;
            }
            $this->ArgMod = $arg_mod;
        }


        /*
        for($i=0; $i<count($request_uri_arr); $i++){
            if ($request_uri_arr[$i] == $modul_index){
            // если URI содержит имя текущего модуля, создаем массив аргументов и переходим к след итерации
                $arg_arr = array();
                continue;
            }
            if (isset($arg_arr)){
            // когда массив аргументов создан, начинаем их вытягивать из УРИ
                $arg_arr[] = $request_uri_arr[$i]; 
            }
        }//
        if(isset($index) AND isset($arg_arr[$index]))
          return  $arg_arr[$index];
        elseif (!isset($index) AND isset($arg_arr))
          return $arg_arr;
        elseif (isset($index) AND isset($arg_arr) AND !isset($arg_arr[$index]))
          return false;
        */
        return false;
    } // -- getURIarg()

    function isUserAuth($user = 'user'){

        switch($user){
            case 'user':

                if(isset($_SESSION['user']->name))
                    return true;
                break;

            case 'admin':

                if(isset($_SESSION['admin']->name))
                    return true;
                break;

            default:
                break;
        }

        return false;

    } // -- isUserAuth

    static function getFrontControllerInstance(){
        if (!isset(self::$front_controller_instance)) {
            $className = __CLASS__;
            self::$front_controller_instance =  $className;
        }
        return self::$front_controller_instance;
    } // --

    function setNoRender(){
        $this->registry->no_render = true;
    }

    function json($data){
        //TODO проверить
        $jsonObject = Zend\Json\Json::encode($data, true);

        echo $jsonObject;
    }

    static function encodeJson($data){
        $options = array();
        //$options['enableJsonExprFinder'] = 1;
        return Zend\Json\Json::encode($data, true, $options);
    }

    function toJson($data){
        $serializer = new \Zend\Serializer\Adapter\Json;
        $res = $serializer->serialize($data);

        unset($serializer);

        echo $res;
    }

    function jsonSend($arr) {
        ///header('Content-Type: application/json; charset=utf-8');
        header('Content-Type: text/x-json; charset=utf-8');
        //header('X-JSON: '.$myJsonData);
        header("Cache-control:no-cache");


        //echo json_encode($arr, JSON_FORCE_OBJECT);
        //fb(json_encode($result, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ));

        echo json_encode($arr);

    }

    function headCodeDynamic($code){
        $this->registry->head_code_dynamic .= $code . "\r\n\r\n";
    }

    static function appendHeadCodeDynamic($code){
        $registry = Registry::getInstance();
        $registry->head_code_dynamic .= $code . "\r\n\r\n";
        unset($registry);
    }

    function headCode($code){

        $this->registry->head_code .= $code . "\r\n\r\n";
    }

    static  function appendHeadCode($code){

        $registry = Registry::getInstance();
        $registry->head_code .= $code . "\r\n\r\n";
        unset($registry);
    }

    function headScript($script){

        if($this->registry->has('head_script_array'))
            $head_script_array = $this->registry->head_script_array;
        else
            $head_script_array = array();

        $head_script_array[] = $script;

        $this->registry->head_script_array = $head_script_array;
    }

    function headLink($link){

        if($this->registry->has('head_link_array'))
            $head_link_array = $this->registry->head_link_array;
        else
            $head_link_array = array();

        $head_link_array[] = $link;

        $this->registry->head_link_array = $head_link_array;
    }

    static function appendHeadLink($link){

        $registry = Registry::getInstance();

        if($registry->has('head_link_array'))
            $head_link_array = $registry->head_link_array;
        else
            $head_link_array = array();

        $head_link_array[] = $link;

        $registry->head_link_array = $head_link_array;

        unset($registry);
    }

    static function appendHeadScript($link){

        $registry = Registry::getInstance();

        if($registry->has('head_script_array'))
            $head_script_array = $registry->head_script_array;
        else
            $head_script_array = array();

        $head_script_array[] = $link;

        $registry->head_script_array = $head_script_array;

        unset($registry);
    }

    function jquery(){
        $jquery = "<script type=\"text/javascript\" src=\"".PUBLIC_URL . "/js/jquery.js" ."\"></script>";

        return $jquery;
    }

    function parseHeadScriptArr(){
        $script = '';
        $head_script_array = null;

        if($this->registry->has('head_script_array'))
            $head_script_array = $this->registry->head_script_array;

        $head_script_array = (array)$head_script_array;

        if(count($head_script_array) > 0){
            $head_script_array = array_unique($head_script_array);

            foreach($head_script_array as $k => $v){
                $script .= "<script type=\"text/javascript\" src=\"". $v ."\"></script>\r\n";
            }
        }

        return $script;

    }

    function parseHeadLinkArr(){
        $link = '';
        $head_link_array = null;

        if($this->registry->has('head_link_array'))
            $head_link_array = $this->registry->head_link_array;

        $head_link_array = (array)$head_link_array;

        if(count($head_link_array) > 0){
            $head_link_array = array_unique($head_link_array);

            foreach($head_link_array as $k => $v){
                $link .= " <link rel=\"stylesheet\" type=\"text/css\" href=\"".$v."\" media=\"screen\" />\r\n";
            }
        }

        return $link;
    }

    function initialStyleSheets(){

        $this->headLink(PUBLIC_URL . '/css/reset.css');
        $this->headLink(PUBLIC_URL . '/css/general.css');
        $this->headLink(PUBLIC_URL . '/css/_general.css');
        $this->headLink(PUBLIC_URL . '/css/text.css');
        $this->headLink(PUBLIC_URL . '/css/layout.css');
        $this->headLink(PUBLIC_URL . '/css/nav.css');
        $this->headLink(PUBLIC_URL . '/css/pro_pages_style.css');
        $this->headLink(PUBLIC_URL . '/css/superfish.css');
        $this->headLink(PUBLIC_URL . '/css/forms.css');
        $this->headLink(PUBLIC_URL . '/css/prettyPhoto.css');
        $this->headLink(PUBLIC_URL . '/css/jquery.snippet.min.css');
        $this->headLink(PUBLIC_URL . '/css/jplayer.blue.monday.css');
        $this->headLink(PUBLIC_URL . '/css/jquery-ui-1.10.3.custom.min.css');
        $this->headLink(PUBLIC_URL . '/css/menu.css');

    }


}